﻿#pragma once
#include "Comm.h"

namespace COMM
{
	class COMM_API Buffer
	{
	public:
		explicit Buffer(size_t size=0);
		Buffer(const void* ptr, size_t size);
		Buffer(const Buffer& rhs);
		Buffer& operator=(const Buffer& rhs);
		virtual ~Buffer(void);
		void release();

		operator char*();
		operator const char*() const;
		char* get();
		const char* get() const;
		size_t capacity() const;
		size_t size() const;
		Buffer& memset(int val=0);
		// do not change the content and size() of buffer.
		// zero_memory: whether zero increased memory.
		Buffer& reserve(size_t size, bool zero_memory = false);
		// do not change the content, only change size() of buffer.
		// zero_memory: whether zero increased or decreased memory.
		Buffer& resize(size_t size, bool zero_memory = true);
		Buffer& consume(size_t size);
		Buffer& append(const void* ptr, int size);
		Buffer& append(const Buffer& rhs);

		static void* malloc(size_t size);
		static void* calloc(size_t num, size_t size);
		static void* realloc(void* ptr, size_t size);
		static void free(void* ptr);

	protected:
		char* m_buffer;
		size_t m_size;
		size_t m_capacity;
	};

	class StringList;
	class COMM_API String : public Buffer
	{
	public:
		static String Empty;
		explicit String(int length);
		String(const char* src = NULL, int len = 0); 

		const char* operator*() const;
		char& operator[](int index);
		const char& operator[](int index) const;
		bool null() const;
		bool empty() const;
		int length() const;
		bool equal(const String& src, bool ignorecase = false) const;
		String& append(const String& src);
		String& operator+=(const String& src);
		String& operator<<(const String& src);
		String operator+(const String& src) const;
		bool operator==(const String& src) const;
		bool operator!=(const String& src) const;
		bool operator==(const char* src) const;
		bool operator!=(const char* src) const;

		int toint() const;
		long long tolong() const;
		double todouble() const;
		String& tolower();
		String& toupper();
		String& reverse();
		String& trimleft();
		String& trimright();
		String& trim();
		String& replace(const String& substr, const String& newstr, bool replaceall = true);
		String& remove(const String& substr, bool removeall = true);
		bool find(const String& str) const;
		bool startwith(const String& str) const;
		bool endwith(const String& str) const;
		StringList split(const String& seperators) const;

		String& strcat(const String& src);
		String& vsprintf(const char* format, va_list args);
		String& sprintf(const char* format, ...);

		static char* strdup(const char* src); // strdup has bugs in windows linked in different CRT.
		static int strlen(const char* src);

		static bool equal(const char* src, const char* str, bool ignorecase = false);
		static String join(const char* src, const char* str);
		static String tolower(const char* src);
		static String toupper(const char* src);
		static String reverse(const char* src);
		static String trimleft(const char* src);
		static String trimright(const char* src);
		static String trim(const char* src);
		static bool find(const char* src, const char* str);
		static bool startwith(const char* src, const char* str);
		static bool endwith(const char* src, const char* str);
		static StringList split(const char* src, const char* seperators);
		static String format(const char* format, ...);
		static String format(int size, const char* format, ...);

		static String from(unsigned short num);
		static String from(unsigned int num);
		static String from(unsigned long num);
		static String from(unsigned long long num);
		static String from(short num);
		static String from(int num);
		static String from(long num);
		static String from(long long num);
		static String from(float num);
		static String from(double num);
	};


	class COMM_API StringList
	{
	public:
		StringList();
		StringList(const StringList& rhs);
		StringList& operator=(const StringList& rhs);
		virtual ~StringList();

		int count() const;
		String& get(int index);
		const String& get(int index) const;
		String& operator[](int index);
		const String& operator[](int index) const;
		StringList& append(const String& inst);
		StringList& insert(int index, const String& inst);
		StringList& remove(int index);
		StringList& clear();
		StringList& operator<<(const String& inst);

		String join(const char* seperators) const;

	private:
		void* m_list;
	};

}

